www.gusucode.com > 一个美化窗口实例 VC++漂亮界面源码程序 > 一个美化窗口实例 VC++漂亮界面/其它可以引用的类源码/VC++菜单类的演示/MyButton.cpp
#include "stdafx.h" #include "math.h" #include "MyButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMyButton // download by http:www.codesc.net CMyButton::CMyButton() { m_clrText=RGB(0,0,0); m_clrBack=RGB(161,192,245); m_clrLeft=RGB(97,244,78); m_clrRight=RGB(52,148,39); m_clrFlatBack=GetSysColor(COLOR_3DFACE); m_blnMouseOn=FALSE; intStyle=0; intAlgin=0; intButtonFace=0; m_BackBrush.CreateSolidBrush(m_clrFlatBack); } CMyButton::~CMyButton() { m_rgn.DeleteObject(); DestroyXIcon(); m_BackBrush.DeleteObject(); } BEGIN_MESSAGE_MAP(CMyButton, CButton) //{{AFX_MSG_MAP(CMyButton) ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyButton message handlers void CMyButton::PreSubclassWindow() { CButton::PreSubclassWindow(); ModifyStyle(0, BS_OWNERDRAW); CRect rect; GetClientRect(rect); m_rgn.DeleteObject(); SetWindowRgn(NULL, FALSE); if(intButtonFace==1) m_rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,10,10); if(intButtonFace==0) m_rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom); if(intButtonFace==2) m_rgn.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom); SetWindowRgn(m_rgn, TRUE); ClientToScreen(rect); CWnd* pParent = GetParent(); if (pParent) pParent->ScreenToClient(rect); MoveWindow(rect.left, rect.top, rect.Width(), rect.Height(), TRUE); } void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ASSERT(lpDrawItemStruct != NULL); CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rect = lpDrawItemStruct->rcItem; UINT state = lpDrawItemStruct->itemState; UINT nStyle = GetStyle(); CRgn rgn1,rgn2; int r1,g1,b1; if(intButtonFace==1) { rgn1.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,10,10); rgn2.CreateRoundRectRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1,10,10); } if(intButtonFace==0) { rgn1.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom); rgn2.CreateRectRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1); } if(intButtonFace==2) { rgn1.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom); rgn2.CreateEllipticRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1); } pDC->SelectClipRgn(&rgn1); int nSavedDC = pDC->SaveDC(); CBrush brush1,brush2; if(!(nStyle&BS_NOTIFY)) { if ((state & ODS_FOCUS)||(state & ODS_SELECTED)) { if(intStyle!=2) { r1=GetRValue(m_clrBack); g1=GetGValue(m_clrBack); b1=GetBValue(m_clrBack); for(int i=rect.Height()/2;i>0;i--) { r1=(r1+10)>255?255:(r1+10); g1=(g1+10)>255?255:(g1+10); b1=(b1+10)>255?255:(b1+10); CPen pen(PS_SOLID, 1, RGB(r1, g1, b1)); CPen *old = pDC->SelectObject(&pen); pDC->MoveTo(rect.left,rect.top+i); pDC->LineTo(rect.right,rect.top+i); pDC->MoveTo(rect.left,rect.bottom-i); pDC->LineTo(rect.right,rect.bottom-i); pDC->SelectObject(old); } } else { pDC->FillSolidRect(rect,m_clrBack); } r1=GetRValue(m_clrRight); g1=GetGValue(m_clrRight); b1=GetBValue(m_clrRight); r1=(r1+30)>255?255:(r1+30); g1=(g1+30)>255?255:(g1+30); b1=(b1+30)>255?255:(b1+30); brush2.CreateSolidBrush(m_clrRight); brush1.CreateSolidBrush(RGB(r1,g1,b1)); pDC->FrameRgn(&rgn1,&brush1,1,1); pDC->FrameRgn(&rgn2,&brush2,1,1); } else if(m_blnMouseOn) { if(intStyle!=2) { r1=GetRValue(m_clrBack); g1=GetGValue(m_clrBack); b1=GetBValue(m_clrBack); for(int i=rect.Height()/2;i>0;i--) { r1=(r1+10)>255?255:(r1+10); g1=(g1+10)>255?255:(g1+10); b1=(b1+10)>255?255:(b1+10); CPen pen(PS_SOLID, 1, RGB(r1, g1, b1)); CPen *old = pDC->SelectObject(&pen); pDC->MoveTo(rect.left,rect.top+i); pDC->LineTo(rect.right,rect.top+i); pDC->MoveTo(rect.left,rect.bottom-i); pDC->LineTo(rect.right,rect.bottom-i); pDC->SelectObject(old); } } else { pDC->FillSolidRect(rect,m_clrBack); } r1=GetRValue(m_clrLeft); g1=GetGValue(m_clrLeft); b1=GetBValue(m_clrLeft); r1=(r1+30)>255?255:(r1+30); g1=(g1+30)>255?255:(g1+30); b1=(b1+30)>255?255:(b1+30); brush2.CreateSolidBrush(m_clrLeft); brush1.CreateSolidBrush(RGB(r1,g1,b1)); pDC->FrameRgn(&rgn1,&brush1,1,1); pDC->FrameRgn(&rgn2,&brush2,1,1); } else { if(nStyle&BS_FLAT) { CBrush bs; bs.CreateSolidBrush(m_clrFlatBack); CRect rcBack; GetClientRect(rcBack); pDC->FillRect(rcBack,&m_BackBrush); } else { if(intStyle!=2) { r1=GetRValue(m_clrBack); g1=GetGValue(m_clrBack); b1=GetBValue(m_clrBack); for(int i=rect.Height()/2;i>0;i--) { r1=(r1+13)>255?255:(r1+13); g1=(g1+13)>255?255:(g1+13); b1=(b1+13)>255?255:(b1+13); CPen pen(PS_SOLID, 1, RGB(r1, g1, b1)); CPen *old = pDC->SelectObject(&pen); pDC->MoveTo(rect.left,rect.top+i); pDC->LineTo(rect.right,rect.top+i); pDC->MoveTo(rect.left,rect.bottom-i); pDC->LineTo(rect.right,rect.bottom-i); pDC->SelectObject(old); } } else { pDC->FillSolidRect(rect,m_clrBack); } r1=GetRValue(m_clrBack); g1=GetGValue(m_clrBack); b1=GetBValue(m_clrBack); r1=(r1+30)>255?255:(r1+30); g1=(g1+30)>255?255:(g1+30); b1=(b1+30)>255?255:(b1+30); brush2.CreateSolidBrush(m_clrBack); brush1.CreateSolidBrush(RGB(r1,g1,b1)); pDC->FrameRgn(&rgn1,&brush1,1,1); pDC->FrameRgn(&rgn2,&brush2,1,1); } } } else { pDC->FillSolidRect(rect,m_clrBack); } //输出文字 CFont *ft=GetFont(); LOGFONT logft; ft->GetLogFont(&logft); CRect rcIcon(rect); if(intStyle==1) { switch(intAlgin) { case 1: //文字在下端 rcIcon.bottom=rect.bottom-abs(logft.lfHeight); if(rcIcon.bottom<0) rcIcon.bottom=0; DrawIconX(pDC,rcIcon); rect.top=rcIcon.bottom-(rcIcon.Height()-dwIconHeight)/2; break; case 2://文字在上 rcIcon.top=abs(logft.lfHeight)+rect.top; DrawIconX(pDC,rcIcon); rect.bottom=rcIcon.top+(rcIcon.Height()-dwIconHeight)/2; break; case 3://文字在左 GetXiconInf(); rcIcon.left=(long)(rect.Width()*0.9+rect.left-dwIconWidth-5); rcIcon.right=(long)(rect.Width()*0.9+rect.left); DrawIconX(pDC,rcIcon); rect.right=rcIcon.left; break; case 0://文字在右 default: DrawIconX(pDC,rcIcon); rect.left=(long)(dwIconWidth+rect.left+rect.Width()*0.1); break; } } if(intStyle==0) { switch(intAlgin) { case 1: //文字在下端 rect.top=rect.bottom-abs(logft.lfHeight)-10; break; case 2://文字在上 rect.bottom=abs(logft.lfHeight)+10+rect.top; break; case 3://文字在左 case 0://文字在右 default: break; } } if(intStyle==2) { pDC->FrameRgn(&rgn1,&brush1,1,1); pDC->FrameRgn(&rgn2,&brush2,1,1); switch(intAlgin) { case 1: //文字在下端 rcIcon.bottom=rect.bottom-abs(logft.lfHeight); if(rcIcon.bottom<0) rcIcon.bottom=0; DrawImgX(pDC,rcIcon); rect.top=rcIcon.bottom-(rcIcon.Height()-m_imgSize.cy)/2; break; case 2://文字在上 rcIcon.top=abs(logft.lfHeight)+rect.top; DrawImgX(pDC,rcIcon); rect.bottom=rcIcon.top+(rcIcon.Height()-m_imgSize.cy)/2; break; case 3://文字在左 rcIcon.left=(long)(rect.Width()*0.9+rect.left-m_imgSize.cx-5); rcIcon.right=(long)(rect.Width()*0.9+rect.left); DrawImgX(pDC,rcIcon); rect.right=rcIcon.left; break; case 0://文字在右 default: DrawImgX(pDC,rcIcon); rect.left=(long)(m_imgSize.cx+rect.left+rect.Width()*0.1); break; } } CPoint m_ptCentre=rect.CenterPoint(); CString strText; GetWindowText(strText); if (!strText.IsEmpty()) { pDC->SetTextColor(m_clrText); CSize Extent = pDC->GetTextExtent(strText); CPoint pt; if(intAlgin==1 || intAlgin==2) { pt.x = m_ptCentre.x - Extent.cx/2; pt.y=m_ptCentre.y - Extent.cy/2; } if(intAlgin==0) { pt.x=rect.left+15; pt.y=m_ptCentre.y - Extent.cy/2; } if(intAlgin==3) { pt.x=rect.right-Extent.cy-10; pt.y=m_ptCentre.y - Extent.cy/2; } if (state & ODS_SELECTED) pt.Offset(1,1); pDC->SetBkMode(TRANSPARENT); if ((state & ODS_DISABLED)&!(nStyle&BS_NOTIFY)) pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); else if(nStyle&BS_NOTIFY) { pDC->FillRect(rect,&m_BackBrush); if((state & ODS_FOCUS)||(state & ODS_SELECTED)) { pDC->SetTextColor(m_clrRight); pDC->TextOut(pt.x+2, pt.y+2, strText); } else if(m_blnMouseOn) { pDC->SetTextColor(m_clrLeft); pDC->TextOut(pt.x+2, pt.y+2, strText); } else { pDC->TextOut(pt.x, pt.y, strText); } } else { pDC->TextOut(pt.x, pt.y, strText); } } pDC->SelectClipRgn(NULL); pDC->RestoreDC(nSavedDC); rgn1.DeleteObject(); rgn2.DeleteObject(); } void CMyButton::SetMaskColor(COLORREF colLeft,COLORREF colRight) { m_clrRight=colRight; m_clrLeft=colLeft; this->Invalidate(TRUE); } void CMyButton::SetBackColor(COLORREF color) { m_clrBack=color; this->Invalidate(TRUE); } void CMyButton::SetBackImage(UINT nIDResource) { CBitmap bmp; intStyle=3; bmp.LoadBitmap(nIDResource); m_BackBrush.DeleteObject(); m_BackBrush.CreatePatternBrush(&bmp); } void CMyButton::SetButtonFace(int intStyle) { intButtonFace=intStyle; this->Invalidate(); } void CMyButton::SetFlatBack(COLORREF colFlat) { m_clrFlatBack=colFlat; m_BackBrush.DeleteObject(); m_BackBrush.CreateSolidBrush(colFlat); this->Invalidate(TRUE); } void CMyButton::SetTextColor(COLORREF color) { m_clrText=color; this->Invalidate(TRUE); } void CMyButton::OnMouseMove(UINT nFlags, CPoint point) { CWnd* wndUnderMouse = NULL; CWnd* wndActive = this; TRACKMOUSEEVENT csTME; CButton::OnMouseMove(nFlags, point); ClientToScreen(&point); wndUnderMouse = WindowFromPoint(point); // If the mouse enter the button with the left button pressed then do nothing if (nFlags & MK_LBUTTON) return; // If our button is not flat then do nothing wndActive = GetActiveWindow(); if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive) { if (!m_blnMouseOn) { m_blnMouseOn = TRUE; Invalidate(); csTME.cbSize = sizeof(csTME); csTME.dwFlags = TME_LEAVE; csTME.hwndTrack = m_hWnd; ::_TrackMouseEvent(&csTME); } } else { m_blnMouseOn=FALSE; Invalidate(); } } LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam) { m_blnMouseOn=FALSE; Invalidate(); return 0; } void CMyButton::SetXIcon(UINT nIDResource) { intStyle=1; Xicon=AfxGetApp()->LoadIcon(nIDResource); this->Invalidate(); } void CMyButton::DrawIconX(CDC *pDC,CRect rcItem) { GetXiconInf(); int intTop=(rcItem.Height()-dwIconHeight)/2; if(intTop<0) intTop=0; intTop=rcItem.top+intTop; if(intAlgin==0) { int intLeft=rcItem.left+(int)(rcItem.Width()*0.1); pDC->DrawIcon(intLeft,intTop,Xicon); } else { int intLeft=(rcItem.Width()-dwIconWidth)/2; if(intLeft<0) intLeft=0; intLeft=intLeft+rcItem.left; pDC->DrawIcon(intLeft,intTop,Xicon); } } void CMyButton::DrawImgX(CDC *pDC,CRect rcItem) { int cx,cy; if(intAlgin==0) { cx=rcItem.left+(int)(rcItem.Width()*0.1); cy=(rcItem.Height()-m_imgSize.cy)/2+rcItem.top; } else { cx=(rcItem.Width()-m_imgSize.cx)/2+rcItem.left; cy=(rcItem.Height()-m_imgSize.cy)/2+rcItem.top; } CPoint pt(cx,cy); m_imgList.Draw(pDC,0,pt,ILD_NORMAL); } void CMyButton::DestroyXIcon() { if(Xicon) ::DestroyIcon(Xicon); } void CMyButton::GetXiconInf() { BOOL bRetValue; ICONINFO ii; if (Xicon) { ::ZeroMemory(&ii, sizeof(ICONINFO)); bRetValue = ::GetIconInfo(Xicon, &ii); if (bRetValue == FALSE) { DestroyXIcon(); } // if dwIconWidth = (DWORD)(ii.xHotspot * 2); dwIconHeight= (DWORD)(ii.yHotspot * 2); ::DeleteObject(ii.hbmMask); ::DeleteObject(ii.hbmColor); } } void CMyButton::SetXAlign(int Align) { intAlgin=Align; this->Invalidate(); } void CMyButton::SetXStyle(int Style) { intStyle=Style; this->Invalidate(); } void CMyButton::SetForeImage(UINT nIDResource,CSize sz) { intStyle=2; m_imgSize=sz; HBITMAP hbm=(HBITMAP)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION |LR_LOADMAP3DCOLORS); CBitmap bm; bm.Attach(hbm); m_imgList.Create(sz.cx,sz.cy,ILC_COLOR16,0,0); m_imgList.Add(&bm,(CBitmap*)NULL); }